package dolmisani.toys.emulators.j2600;

import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

import java.io.*;
import jstella.core.*;
import javax.swing.*;

import javax.swing.UIManager.LookAndFeelInfo;
import jstella.runner.InputMaster;
import jstella.runner.Intercessor;
import jstella.runner.JStellaConfigurationDialog;
import jstella.runner.JStellaHelp;


import static jstella.core.JSConstants.*;

/**
 *
 * @author Daniele Olmisani <daniele.olmisani@gmail.com>
 */
public class J2600Main extends javax.swing.JFrame implements Intercessor.IfcIntercessorClient {

    //Here's something crazy...if you find that opening dialogs takes a really long time (10-20 seconds),
    //and you are using Windows (perhaps only true with Vista), clean up your desktop, especially of all the large zip and jar files...
    // The following is Java6 only, so I'm hesitant to use it.'
    // public static javax.swing.filechooser.FileNameExtensionFilter ROMFileFilter=new javax.swing.filechooser.FileNameExtensionFilter("ROM files","bin");
    public final static String CONFIG_KEY_DEFAULT_ROM_DIR = "jstella.romdir";
    public final static String CONFIG_KEY_DEFAULT_STATE_DIR = "jstella.statedir";
    public final static String CONFIG_KEY_DEFAULT_SCREEN = "jstella.defaultscreen";
    public final static String CONFIG_VALUE_DEFAULT_SCREEN_SNOW = "snow";
    public final static String CONFIG_VALUE_DEFAULT_SCREEN_TEST_PATTERN = "testpattern";
    public final static String CONFIG_FILENAME = "jstella.cfg";
    public final static String DEFAULT_STATE_NAME = "mysavedgame.jssg";
    private final static String WINDOW_TITLE = "JStella " + JSConstants.JSTELLA_VERSION;
    //private String myJavaVersion = "<VERSION>";
    private java.util.Map<String, String> myConfiguration = new java.util.HashMap<String, String>();
    private Intercessor myIntercessor = null;
    private File myCurrentROMFile = null;
    private String myROMDirectory = "";
    private String myStateDirectory = "";
    private String myDefaultStateName = "";

    /**
     * Creates new form J2600Main
     */
    public J2600Main() {

        initComponents();

        System.out.println("Java version: " + System.getProperty("java.version"));
        System.out.println("JStella version: " + JSTELLA_VERSION);

        //java.awt.Toolkit.getDefaultToolkit().
        //Handle configuration
        boolean zConfigLoaded = loadConfig();
        if (zConfigLoaded == false) {
            useDefaultConfiguration();
        } else if ((zConfigLoaded == true) && (InputMaster.checkConfigMapForControls(myConfiguration) == false)) {
            System.out.println("JStella configuration file lacks control settings...adding default control settings");
            useDefaultConfiguration();
        }//end : config lacks control settings


        this.setTitle(WINDOW_TITLE);
        myIntercessor = new Intercessor(this);
        myIntercessor.setControls(myConfiguration);
        myIntercessor.setAutoPauseMode(true);
        //  initConsole(new JSConsole());
        initAboutDialog();
        updateOptions();
        updateCartridgeStatus();



        // CurrentOSystem=new JSOSystem();

    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        FCMain = new javax.swing.JFileChooser();
        DialogAbout = new javax.swing.JDialog();
        PanelAboutSouth = new javax.swing.JPanel();
        ButtonAboutOK = new javax.swing.JButton();
        TPAbout = new javax.swing.JTextPane();
        ButtonGroupChannels = new javax.swing.ButtonGroup();
        ButtonGroupTVType = new javax.swing.ButtonGroup();
        ButtonGroupP0Difficulty = new javax.swing.ButtonGroup();
        ButtonGroupP1Difficulty = new javax.swing.ButtonGroup();
        MBMain = new javax.swing.JMenuBar();
        MenuFile = new javax.swing.JMenu();
        MILoadROM = new javax.swing.JMenuItem();
        SepFileA = new javax.swing.JSeparator();
        MISaveState = new javax.swing.JMenuItem();
        MILoadState = new javax.swing.JMenuItem();
        SepFileB = new javax.swing.JSeparator();
        MIEnableAdvancedMenu = new javax.swing.JMenuItem();
        SepFileC = new javax.swing.JSeparator();
        MIExit = new javax.swing.JMenuItem();
        jMenu1 = new javax.swing.JMenu();
        jMenuItem2 = new javax.swing.JMenuItem();
        jMenuItem3 = new javax.swing.JMenuItem();
        jMenuItem4 = new javax.swing.JMenuItem();
        jMenuItem1 = new javax.swing.JMenuItem();
        jMenuItem5 = new javax.swing.JMenuItem();
        MenuOptions = new javax.swing.JMenu();
        CBMIPaused = new javax.swing.JCheckBoxMenuItem();
        SepOptionsA = new javax.swing.JSeparator();
        CBMISoundEnabled = new javax.swing.JCheckBoxMenuItem();
        MenuSoundChannels = new javax.swing.JMenu();
        RBMIMonoSound = new javax.swing.JRadioButtonMenuItem();
        RBMIStereoSound = new javax.swing.JRadioButtonMenuItem();
        SepOptionsB = new javax.swing.JSeparator();
        CBMIPhosphorEnabled = new javax.swing.JCheckBoxMenuItem();
        CBMILetterBoxMode = new javax.swing.JCheckBoxMenuItem();
        SepOptionsC = new javax.swing.JSeparator();
        MIConfigure = new javax.swing.JMenuItem();
        MenuControls = new javax.swing.JMenu();
        MIVirtualJoystick = new javax.swing.JMenuItem();
        MenuSwitches = new javax.swing.JMenu();
        MIReset = new javax.swing.JMenuItem();
        MISelect = new javax.swing.JMenuItem();
        MenuTVType = new javax.swing.JMenu();
        RBMIBWTelevision = new javax.swing.JRadioButtonMenuItem();
        RBMIColorTelevision = new javax.swing.JRadioButtonMenuItem();
        MenuPlayer0Difficulty = new javax.swing.JMenu();
        RBMIPlayer0Amateur = new javax.swing.JRadioButtonMenuItem();
        RBMIPlayer0Professional = new javax.swing.JRadioButtonMenuItem();
        MenuPlayer1Difficulty = new javax.swing.JMenu();
        RBMIPlayer1Amateur = new javax.swing.JRadioButtonMenuItem();
        RBMIPlayer1Professional = new javax.swing.JRadioButtonMenuItem();
        MenuAdvanced = new javax.swing.JMenu();
        MIChangeYStart = new javax.swing.JMenuItem();
        MIChangeDisplayHeight = new javax.swing.JMenuItem();
        MenuHelp = new javax.swing.JMenu();
        MIHelpContents = new javax.swing.JMenuItem();
        MIAbout = new javax.swing.JMenuItem();

        DialogAbout.setTitle("About JStella");
        DialogAbout.setAlwaysOnTop(true);
        DialogAbout.setLocationByPlatform(true);
        DialogAbout.setModal(true);
        DialogAbout.setResizable(false);

        ButtonAboutOK.setText("OK");
        ButtonAboutOK.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ButtonAboutOKActionPerformed(evt);
            }
        });
        PanelAboutSouth.add(ButtonAboutOK);

        DialogAbout.getContentPane().add(PanelAboutSouth, java.awt.BorderLayout.SOUTH);

        TPAbout.setBorder(null);
        TPAbout.setEditable(false);
        TPAbout.setFocusable(false);
        TPAbout.setOpaque(false);
        DialogAbout.getContentPane().add(TPAbout, java.awt.BorderLayout.CENTER);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("JStella");
        setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));

        MenuFile.setMnemonic('F');
        MenuFile.setText("File");

        MILoadROM.setMnemonic('O');
        MILoadROM.setText("Open and play cartridge file");
        MILoadROM.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MILoadROMActionPerformed(evt);
            }
        });
        MenuFile.add(MILoadROM);
        MenuFile.add(SepFileA);

        MISaveState.setMnemonic('S');
        MISaveState.setText("Save current game");
        MISaveState.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MISaveStateActionPerformed(evt);
            }
        });
        MenuFile.add(MISaveState);

        MILoadState.setMnemonic('L');
        MILoadState.setText("Load a saved game");
        MILoadState.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MILoadStateActionPerformed(evt);
            }
        });
        MenuFile.add(MILoadState);
        MenuFile.add(SepFileB);

        MIEnableAdvancedMenu.setText("Enable Advanced Menu");
        MIEnableAdvancedMenu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MIEnableAdvancedMenuActionPerformed(evt);
            }
        });
        MenuFile.add(MIEnableAdvancedMenu);
        MenuFile.add(SepFileC);

        MIExit.setMnemonic('x');
        MIExit.setText("Exit JStella");
        MIExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MIExitActionPerformed(evt);
            }
        });
        MenuFile.add(MIExit);

        MBMain.add(MenuFile);

        jMenu1.setText("Games");

        jMenuItem2.setText("Adventure");
        jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem2ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem2);

        jMenuItem3.setText("Asteroids");
        jMenuItem3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem3ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem3);

        jMenuItem4.setText("Battlezone");
        jMenuItem4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem4ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem4);

        jMenuItem1.setText("Centipede");
        jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem1ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem1);

        jMenuItem5.setText("Defender2");
        jMenuItem5.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem5ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem5);

        MBMain.add(jMenu1);

        MenuOptions.setMnemonic('O');
        MenuOptions.setText("Options");

        CBMIPaused.setMnemonic('P');
        CBMIPaused.setText("Pause");
        CBMIPaused.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                CBMIPausedActionPerformed(evt);
            }
        });
        MenuOptions.add(CBMIPaused);
        MenuOptions.add(SepOptionsA);

        CBMISoundEnabled.setMnemonic('S');
        CBMISoundEnabled.setSelected(true);
        CBMISoundEnabled.setText("Sound enabled");
        CBMISoundEnabled.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                CBMISoundEnabledActionPerformed(evt);
            }
        });
        MenuOptions.add(CBMISoundEnabled);

        MenuSoundChannels.setMnemonic('c');
        MenuSoundChannels.setText("Audio channels");

        ButtonGroupChannels.add(RBMIMonoSound);
        RBMIMonoSound.setMnemonic('M');
        RBMIMonoSound.setSelected(true);
        RBMIMonoSound.setText("Mono");
        RBMIMonoSound.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                RBMIMonoSoundActionPerformed(evt);
            }
        });
        MenuSoundChannels.add(RBMIMonoSound);

        ButtonGroupChannels.add(RBMIStereoSound);
        RBMIStereoSound.setMnemonic('S');
        RBMIStereoSound.setText("Stereo");
        RBMIStereoSound.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                RBMIStereoSoundActionPerformed(evt);
            }
        });
        MenuSoundChannels.add(RBMIStereoSound);

        MenuOptions.add(MenuSoundChannels);
        MenuOptions.add(SepOptionsB);

        CBMIPhosphorEnabled.setMnemonic('f');
        CBMIPhosphorEnabled.setText("Anti-flicker mode");
        CBMIPhosphorEnabled.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                CBMIPhosphorEnabledActionPerformed(evt);
            }
        });
        MenuOptions.add(CBMIPhosphorEnabled);

        CBMILetterBoxMode.setMnemonic('L');
        CBMILetterBoxMode.setText("Letterbox mode");
        CBMILetterBoxMode.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                CBMILetterBoxModeActionPerformed(evt);
            }
        });
        MenuOptions.add(CBMILetterBoxMode);
        MenuOptions.add(SepOptionsC);

        MIConfigure.setMnemonic('C');
        MIConfigure.setText("Configure...");
        MIConfigure.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MIConfigureActionPerformed(evt);
            }
        });
        MenuOptions.add(MIConfigure);

        MBMain.add(MenuOptions);

        MenuControls.setMnemonic('C');
        MenuControls.setText("Controls");

        MIVirtualJoystick.setMnemonic('j');
        MIVirtualJoystick.setText("Toggle virtual joystick");
        MIVirtualJoystick.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MIVirtualJoystickActionPerformed(evt);
            }
        });
        MenuControls.add(MIVirtualJoystick);

        MBMain.add(MenuControls);

        MenuSwitches.setMnemonic('S');
        MenuSwitches.setText("Switches");
        MenuSwitches.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MenuSwitchesActionPerformed(evt);
            }
        });

        MIReset.setMnemonic('R');
        MIReset.setText("Reset (F1)");
        MIReset.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MIResetActionPerformed(evt);
            }
        });
        MenuSwitches.add(MIReset);

        MISelect.setMnemonic('S');
        MISelect.setText("Select (F2)");
        MISelect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MISelectActionPerformed(evt);
            }
        });
        MenuSwitches.add(MISelect);

        MenuTVType.setMnemonic('T');
        MenuTVType.setText("TV Type");

        ButtonGroupTVType.add(RBMIBWTelevision);
        RBMIBWTelevision.setMnemonic('B');
        RBMIBWTelevision.setText("Black and white (F3)");
        RBMIBWTelevision.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                RBMIBWTelevisionActionPerformed(evt);
            }
        });
        MenuTVType.add(RBMIBWTelevision);

        ButtonGroupTVType.add(RBMIColorTelevision);
        RBMIColorTelevision.setMnemonic('C');
        RBMIColorTelevision.setSelected(true);
        RBMIColorTelevision.setText("Color (F4)");
        RBMIColorTelevision.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                RBMIColorTelevisionActionPerformed(evt);
            }
        });
        MenuTVType.add(RBMIColorTelevision);

        MenuSwitches.add(MenuTVType);

        MenuPlayer0Difficulty.setMnemonic('0');
        MenuPlayer0Difficulty.setText("Left player difficulty");

        ButtonGroupP0Difficulty.add(RBMIPlayer0Amateur);
        RBMIPlayer0Amateur.setMnemonic('B');
        RBMIPlayer0Amateur.setSelected(true);
        RBMIPlayer0Amateur.setText("B (amateur) (F5)");
        RBMIPlayer0Amateur.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                RBMIPlayer0AmateurActionPerformed(evt);
            }
        });
        MenuPlayer0Difficulty.add(RBMIPlayer0Amateur);

        ButtonGroupP0Difficulty.add(RBMIPlayer0Professional);
        RBMIPlayer0Professional.setMnemonic('A');
        RBMIPlayer0Professional.setText("A (professional) (F6)");
        RBMIPlayer0Professional.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                RBMIPlayer0ProfessionalActionPerformed(evt);
            }
        });
        MenuPlayer0Difficulty.add(RBMIPlayer0Professional);

        MenuSwitches.add(MenuPlayer0Difficulty);

        MenuPlayer1Difficulty.setMnemonic('1');
        MenuPlayer1Difficulty.setText("Right player difficulty");

        ButtonGroupP1Difficulty.add(RBMIPlayer1Amateur);
        RBMIPlayer1Amateur.setMnemonic('B');
        RBMIPlayer1Amateur.setSelected(true);
        RBMIPlayer1Amateur.setText("B (amateur) (F7)");
        RBMIPlayer1Amateur.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                RBMIPlayer1AmateurActionPerformed(evt);
            }
        });
        MenuPlayer1Difficulty.add(RBMIPlayer1Amateur);

        ButtonGroupP1Difficulty.add(RBMIPlayer1Professional);
        RBMIPlayer1Professional.setMnemonic('A');
        RBMIPlayer1Professional.setText("A (professional) (F8)");
        RBMIPlayer1Professional.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                RBMIPlayer1ProfessionalActionPerformed(evt);
            }
        });
        MenuPlayer1Difficulty.add(RBMIPlayer1Professional);

        MenuSwitches.add(MenuPlayer1Difficulty);

        MBMain.add(MenuSwitches);

        MenuAdvanced.setMnemonic('A');
        MenuAdvanced.setText("Advanced");
        MenuAdvanced.setVisible(false);

        MIChangeYStart.setText("Change Y-Start");
        MIChangeYStart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MIChangeYStartActionPerformed(evt);
            }
        });
        MenuAdvanced.add(MIChangeYStart);

        MIChangeDisplayHeight.setText("Change display height");
        MIChangeDisplayHeight.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MIChangeDisplayHeightActionPerformed(evt);
            }
        });
        MenuAdvanced.add(MIChangeDisplayHeight);

        MBMain.add(MenuAdvanced);

        MenuHelp.setMnemonic('H');
        MenuHelp.setText("Help");

        MIHelpContents.setMnemonic('H');
        MIHelpContents.setText("Help contents");
        MIHelpContents.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MIHelpContentsActionPerformed(evt);
            }
        });
        MenuHelp.add(MIHelpContents);

        MIAbout.setMnemonic('A');
        MIAbout.setText("About");
        MIAbout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MIAboutActionPerformed(evt);
            }
        });
        MenuHelp.add(MIAbout);

        MBMain.add(MenuHelp);

        setJMenuBar(MBMain);

        setSize(new java.awt.Dimension(509, 435));
        setLocationRelativeTo(null);
    }// </editor-fold>//GEN-END:initComponents

    private void MIEnableAdvancedMenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MIEnableAdvancedMenuActionPerformed
        MenuAdvanced.setVisible(true);
    }//GEN-LAST:event_MIEnableAdvancedMenuActionPerformed

    private void MIChangeDisplayHeightActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MIChangeDisplayHeightActionPerformed
        int zOldValue = myIntercessor.getConsole().getDisplayHeight();
        String zValueStr = JOptionPane.showInputDialog(this, "Current display height is " + zOldValue + ". Enter new height:");
        int zNewValue = zOldValue;
        if (zValueStr != null) {
            try {
                zNewValue = Integer.parseInt(zValueStr);
                myIntercessor.getConsole().changeDisplayHeight(zNewValue);
            } catch (NumberFormatException e) {
                JOptionPane.showMessageDialog(this, "Invalid value", "Error", JOptionPane.ERROR_MESSAGE);
            }
        }//end : didn't hit cancel
    }//GEN-LAST:event_MIChangeDisplayHeightActionPerformed

    private void MIChangeYStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MIChangeYStartActionPerformed
        int zOldValue = myIntercessor.getConsole().getYStart();
        String zValueStr = JOptionPane.showInputDialog(this, "Current YStart is " + zOldValue + ". Enter new YStart:");
        int zNewValue = zOldValue;
        if (zValueStr != null) {
            try {
                zNewValue = Integer.parseInt(zValueStr);
                myIntercessor.getConsole().changeYStart(zNewValue);
            } catch (NumberFormatException e) {
                JOptionPane.showMessageDialog(this, "Invalid value", "Error", JOptionPane.ERROR_MESSAGE);
            }
        }//end : didn't hit cancel

    }//GEN-LAST:event_MIChangeYStartActionPerformed

    private void MIExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MIExitActionPerformed
        System.exit(0);
    }//GEN-LAST:event_MIExitActionPerformed

    private void CBMILetterBoxModeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CBMILetterBoxModeActionPerformed
        myIntercessor.setLetterBoxMode(CBMILetterBoxMode.isSelected());
    }//GEN-LAST:event_CBMILetterBoxModeActionPerformed

    private void MIHelpContentsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MIHelpContentsActionPerformed
        JStellaHelp.runJStellaHelp(this);
    }//GEN-LAST:event_MIHelpContentsActionPerformed

    private void MIVirtualJoystickActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MIVirtualJoystickActionPerformed
        myIntercessor.toggleVirtualJoystick(this);
    }//GEN-LAST:event_MIVirtualJoystickActionPerformed

    private void MILoadStateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MILoadStateActionPerformed
        loadState();
    }//GEN-LAST:event_MILoadStateActionPerformed

    private void MISaveStateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MISaveStateActionPerformed
        saveState();
    }//GEN-LAST:event_MISaveStateActionPerformed

    private void MISelectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MISelectActionPerformed
        myIntercessor.emulateSelectPress();
    }//GEN-LAST:event_MISelectActionPerformed

    private void MIConfigureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MIConfigureActionPerformed
        showConfigDialog();
    }//GEN-LAST:event_MIConfigureActionPerformed

    private void RBMIColorTelevisionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_RBMIColorTelevisionActionPerformed
        myIntercessor.setTVTypeBW(false);
    }//GEN-LAST:event_RBMIColorTelevisionActionPerformed

    private void RBMIBWTelevisionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_RBMIBWTelevisionActionPerformed
        myIntercessor.setTVTypeBW(true);
    }//GEN-LAST:event_RBMIBWTelevisionActionPerformed

    private void RBMIPlayer1ProfessionalActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_RBMIPlayer1ProfessionalActionPerformed
        myIntercessor.setPlayer1Amateur(false);
    }//GEN-LAST:event_RBMIPlayer1ProfessionalActionPerformed

    private void RBMIPlayer1AmateurActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_RBMIPlayer1AmateurActionPerformed
        myIntercessor.setPlayer1Amateur(true);
    }//GEN-LAST:event_RBMIPlayer1AmateurActionPerformed

    private void RBMIPlayer0ProfessionalActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_RBMIPlayer0ProfessionalActionPerformed
        myIntercessor.setPlayer0Amateur(false);
    }//GEN-LAST:event_RBMIPlayer0ProfessionalActionPerformed

    private void RBMIPlayer0AmateurActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_RBMIPlayer0AmateurActionPerformed
        myIntercessor.setPlayer0Amateur(true);
    }//GEN-LAST:event_RBMIPlayer0AmateurActionPerformed

    private void CBMIPausedActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CBMIPausedActionPerformed
        myIntercessor.setPausedByPlayer(CBMIPaused.isSelected());

    }//GEN-LAST:event_CBMIPausedActionPerformed

    private void MenuSwitchesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MenuSwitchesActionPerformed
    }//GEN-LAST:event_MenuSwitchesActionPerformed

    private void MIResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MIResetActionPerformed
        myIntercessor.emulateResetPress();
    }//GEN-LAST:event_MIResetActionPerformed

    private void RBMIStereoSoundActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_RBMIStereoSoundActionPerformed
        myIntercessor.setStereoSound(true);
    }//GEN-LAST:event_RBMIStereoSoundActionPerformed

    private void RBMIMonoSoundActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_RBMIMonoSoundActionPerformed
        myIntercessor.setStereoSound(false);
    }//GEN-LAST:event_RBMIMonoSoundActionPerformed

    private void CBMIPhosphorEnabledActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CBMIPhosphorEnabledActionPerformed
        if (myIntercessor != null) {
            myIntercessor.setPhosphorEnabled(CBMIPhosphorEnabled.isSelected());
        }
    }//GEN-LAST:event_CBMIPhosphorEnabledActionPerformed

    private void CBMISoundEnabledActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CBMISoundEnabledActionPerformed

        myIntercessor.setSoundEnabled(CBMISoundEnabled.isSelected());
    }//GEN-LAST:event_CBMISoundEnabledActionPerformed

    private void ButtonAboutOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonAboutOKActionPerformed
        DialogAbout.setVisible(false);

    }//GEN-LAST:event_ButtonAboutOKActionPerformed

    private void MIAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MIAboutActionPerformed
        DialogAbout.setLocationRelativeTo(this);
        DialogAbout.setSize(400, 200);
        DialogAbout.setVisible(true);
        //TODO : guessing size is risky--need a more elegant solution
    }//GEN-LAST:event_MIAboutActionPerformed

    private void MILoadROMActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MILoadROMActionPerformed
        try {
            loadROM();
        }//end : try
        catch (JSException e) {
            respondToException(e);
        }

    }//GEN-LAST:event_MILoadROMActionPerformed

    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem1ActionPerformed
        myIntercessor.playROM(getClass().getResourceAsStream("/dolmisani/toys/emulators/j2600/roms/centipede.bin"));
    }//GEN-LAST:event_jMenuItem1ActionPerformed

    private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem2ActionPerformed
        myIntercessor.playROM(getClass().getResourceAsStream("/dolmisani/toys/emulators/j2600/roms/adventure.bin"));
    }//GEN-LAST:event_jMenuItem2ActionPerformed

    private void jMenuItem3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem3ActionPerformed
        myIntercessor.playROM(getClass().getResourceAsStream("/dolmisani/toys/emulators/j2600/roms/asteroids.bin"));
    }//GEN-LAST:event_jMenuItem3ActionPerformed

    private void jMenuItem4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem4ActionPerformed
        myIntercessor.playROM(getClass().getResourceAsStream("/dolmisani/toys/emulators/j2600/roms/battlezone.bin"));
    }//GEN-LAST:event_jMenuItem4ActionPerformed

    private void jMenuItem5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem5ActionPerformed
        myIntercessor.playROM(getClass().getResourceAsStream("/dolmisani/toys/emulators/j2600/roms/defender2.bin"));
    }//GEN-LAST:event_jMenuItem5ActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        final String zROMDir;
        if (args.length > 0) {
            zROMDir = args[0];
        } else {
            zROMDir = "";
        }



        try {
            for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (Exception e) {
            // If Nimbus is not available, you can set the GUI to another look and feel.
        }
        
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                J2600Main zJSM = new J2600Main();
                zJSM.setROMDirectory(zROMDir);//args[0];
                zJSM.setVisible(true);
            }
        });
    }

    private void setROMDirectory(String aROMDir) {
        myROMDirectory = aROMDir;
        if (aROMDir.trim() != "") {
            FCMain.setCurrentDirectory(new File(aROMDir));
        }
    }

    private void initAboutDialog() {
        //TODO : use html, with a hyperlink for the html

        //Step 1: set attributes for the text
        SimpleAttributeSet zSAS = new SimpleAttributeSet();
        zSAS.addAttribute(StyleConstants.Alignment, StyleConstants.ALIGN_CENTER);
        zSAS.addAttribute(StyleConstants.Bold, Boolean.valueOf(true));

        //Step 2: set the text
        StringBuffer zSBuf = new StringBuffer();
        zSBuf.append("" + JSTELLA_LONGTITLE + "\n");
        zSBuf.append("Version: " + JSTELLA_VERSION + "\n");
        zSBuf.append("" + JSTELLA_BYLINE + "\n");
        zSBuf.append("" + JSTELLA_HTTP + "\n");


        //Step 3 : add the text
        try {
            StyledDocument zSDoc = TPAbout.getStyledDocument();
            zSDoc.remove(0, zSDoc.getLength());
            zSDoc.insertString(0, zSBuf.toString(), null);
            zSDoc.setParagraphAttributes(0, zSDoc.getLength(), zSAS, false);
        }//end : try
        catch (BadLocationException e) {
            e.printStackTrace();
        }
    }

    public boolean respondToException(JSException e) {
        myIntercessor.showDefaultExceptionResponse(e, this);

        return true;
    }

    private void updateOptions() {

        CBMISoundEnabled.setSelected(myIntercessor.isSoundEnabled());
        CBMIPhosphorEnabled.setSelected(myIntercessor.isPhosphorEnabled());
        if (myIntercessor.isStereoSound() == true) {
            RBMIStereoSound.setSelected(true);
        } else {
            RBMIMonoSound.setSelected(true);
        }

        CBMIPaused.setSelected(myIntercessor.isPausedByPlayer());

        if (myIntercessor.isTVTypeBW() == true) {
            RBMIBWTelevision.setSelected(true);
        } else {
            RBMIColorTelevision.setSelected(true);
        }

        if (myIntercessor.isPlayer0Amateur() == true) {
            RBMIPlayer0Amateur.setSelected(true);
        } else {
            RBMIPlayer0Professional.setSelected(true);
        }

        if (myIntercessor.isPlayer1Amateur() == true) {
            RBMIPlayer1Amateur.setSelected(true);
        } else {
            RBMIPlayer1Professional.setSelected(true);
        }

        CBMILetterBoxMode.setSelected(myIntercessor.getLetterBoxMode());
    }

    private String getFileNameWithoutExtension(File aFile) {

        String zFileName = aFile.getName();
        String zReturn = zFileName;
        int zExtensionStart = zFileName.lastIndexOf(".");
        if (zExtensionStart != -1) {
            zReturn = zFileName.substring(0, zExtensionStart);
        }//end : extension found
        return zReturn;
    }

    private void loadROM(File aROMFile) throws IOException {
        FileInputStream zFIS = new FileInputStream(aROMFile);
        myCurrentROMFile = aROMFile;
        System.out.println("Loading ROM : " + aROMFile.toString());
        myIntercessor.playROM(zFIS);
        zFIS.close();

        String zFileNameWithoutExtension = getFileNameWithoutExtension(aROMFile);
        if (zFileNameWithoutExtension != "") {
            myDefaultStateName = zFileNameWithoutExtension + ".jssg";
        } else {
            myDefaultStateName = DEFAULT_STATE_NAME;
        }

    }

    private boolean isValidDirectory(String aDirectory) {

        boolean zReturn = false;
        if ((aDirectory != null) && (aDirectory.trim() != "")) {
            File zDir = new File(aDirectory);
            if (zDir.exists() == true) {
                zReturn = true;
            }
        }
        return zReturn;

    }

    private boolean setCurrentDirectory(String aDirectory) {
        boolean zReturn = false;
        if (isValidDirectory(aDirectory) == true) {
            FCMain.setCurrentDirectory(new File(aDirectory));
            zReturn = true;
        }
        return zReturn;
    }

    private void loadROM() throws JSException {
        try {

            //   System.out.println("Setting directory...");
            if (isValidDirectory(myROMDirectory)) {
                setCurrentDirectory(myROMDirectory);
            } else if (myConfiguration.containsKey(CONFIG_KEY_DEFAULT_ROM_DIR) == true) {
                setCurrentDirectory(myConfiguration.get(CONFIG_KEY_DEFAULT_ROM_DIR));
            }
            //   System.out.println("Setting file filter");
            FCMain.setFileFilter(JSFileFilter.FILTER_ROMS);
            // System.out.println("Showing open dialog...");
            FCMain.setSelectedFile(new File(""));
            int zResult = FCMain.showOpenDialog(this);
            if (zResult == JFileChooser.APPROVE_OPTION) {
                loadROM(FCMain.getSelectedFile());
                myROMDirectory = FCMain.getCurrentDirectory().getPath();
            }//end : approved
        }//end : try
        catch (java.io.IOException e) {
            e.printStackTrace();
        }
        updateCartridgeStatus();
    }

    private void useDefaultConfiguration() {
        myConfiguration = new java.util.HashMap<String, String>();
        InputMaster.addDefaultControlItemsToConfigMap(myConfiguration);

    }

    private File showSaveDialog(String aDefaultDirectory, String aDefaultFileName, JSFileFilter aFilter) {
        //Currently only used for Save State
        File zReturn = null;
        FCMain.setFileFilter(aFilter);
        FCMain.setCurrentDirectory(new File(aDefaultDirectory));
        FCMain.setSelectedFile(new File(aDefaultFileName));

        boolean zChooseAgain = false;
        do {
            int zResult = FCMain.showSaveDialog(this);
            if (zResult == JFileChooser.APPROVE_OPTION) {
                if (FCMain.getSelectedFile().exists() == true) {
                    int zConfirmResult = JOptionPane.showConfirmDialog(this, "" + FCMain.getSelectedFile().getName() + " already exists.  Do you wish to overwrite?");
                    if (zConfirmResult == JOptionPane.NO_OPTION) {
                        zChooseAgain = true;
                    } else if (zConfirmResult == JOptionPane.YES_OPTION) {
                        zReturn = FCMain.getSelectedFile();
                        zChooseAgain = false;
                    }//end : confirmed
                    else {
                        zChooseAgain = false; //cancel
                    }
                }//end : file exists
                else {
                    zReturn = FCMain.getSelectedFile(); //file doesn't exist...therefore okay to save
                }
            }//end : selected a file
            else {
                zChooseAgain = false; //cancelled
            }
        } while (zChooseAgain == true);

        return zReturn;
    }

    private int isSaveAcceptable(File aFileToSave) {
        int zReturn = JOptionPane.YES_OPTION;


        return zReturn;
    }

    private void loadState() //throws JSException
    {
        try {

            if (myStateDirectory.trim() != "") {
                setCurrentDirectory(myStateDirectory);
            } else if (myConfiguration.containsKey(CONFIG_KEY_DEFAULT_STATE_DIR) == true) {
                setCurrentDirectory(myConfiguration.get(CONFIG_KEY_DEFAULT_STATE_DIR));
            }
            FCMain.setFileFilter(JSFileFilter.FILTER_JSTELLA_STATE);
            int zResult = FCMain.showOpenDialog(this);
            if (zResult == JFileChooser.APPROVE_OPTION) {
                FileInputStream zFIS = new FileInputStream(FCMain.getSelectedFile());
                myIntercessor.loadStateFromStream(zFIS);
                updateOptions();
                updateCartridgeStatus();
                myStateDirectory = FCMain.getCurrentDirectory().getPath();
                myDefaultStateName = FCMain.getSelectedFile().getName();
            }//end : approved
        }//end : try
        catch (java.io.ObjectStreamException e) {
            JOptionPane.showMessageDialog(this, "Saved game is incompatible with this version of JStella", "Error loading game", JOptionPane.ERROR_MESSAGE);
            e.printStackTrace();
        } catch (java.io.IOException e) {
            JOptionPane.showMessageDialog(this, "Could not load saved game: " + FCMain.getSelectedFile().getName(), "Error loading game", JOptionPane.ERROR_MESSAGE);

            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            JOptionPane.showMessageDialog(this, "Could not load saved game: " + FCMain.getSelectedFile().getName(), "Error loading game", JOptionPane.ERROR_MESSAGE);

            e.printStackTrace();
        }
        updateCartridgeStatus();

    }

    private void saveState() {
        try {
            JOptionPane.showMessageDialog(this, "Because JStella is still in development, saved games may not be compatible with future releases of JStella", "Warning", JOptionPane.WARNING_MESSAGE);
            String zDefaultDirectory = "";
            if (myStateDirectory.trim() != "") {
                zDefaultDirectory = myStateDirectory;
            } else if (myConfiguration.containsKey(CONFIG_KEY_DEFAULT_STATE_DIR) == true) {
                zDefaultDirectory = myConfiguration.get(CONFIG_KEY_DEFAULT_STATE_DIR);
            }


            File zSelectedFile = showSaveDialog(zDefaultDirectory, myDefaultStateName, JSFileFilter.FILTER_JSTELLA_STATE);


            if (zSelectedFile != null) {
                FileOutputStream zFOS = new FileOutputStream(zSelectedFile);

                myIntercessor.saveStateToStream(zFOS);

                myStateDirectory = FCMain.getCurrentDirectory().getPath();
                myDefaultStateName = zSelectedFile.getName();
                JOptionPane.showMessageDialog(this, "Game saved");
            }//end : approved
        }//end : try
        catch (java.io.IOException e) {
            JOptionPane.showMessageDialog(this, "Could not save current game to file: " + FCMain.getSelectedFile().getName(), "Error saving game", JOptionPane.ERROR_MESSAGE);

            e.printStackTrace();
        }

    }

    private void updateCartridgeStatus() {
        boolean zCartridgeLoaded = (myIntercessor.getCartridge() != null);
        MISaveState.setEnabled(zCartridgeLoaded);

    }

    public void displayCanvas(JPanel aCanvas) {
        this.getContentPane().add(aCanvas, java.awt.BorderLayout.CENTER);
        aCanvas.revalidate();
        aCanvas.requestFocusInWindow();
        //aCanvas.addKeyListener(new JStellaKeyListener());
    }

    private void updatePauseStatus() {
        if (myIntercessor.isPausedByPlayer() == true) {
            this.setTitle(WINDOW_TITLE + " (paused)");
        } else {
            this.setTitle(WINDOW_TITLE);
        }
    }

    public void informUserOfPause(boolean aIsPaused) {
        //if (aIsPaused==true) this.setTitle(WINDOW_TITLE + " (paused)");
        //else this.setTitle(WINDOW_TITLE);
        updatePauseStatus();

    }

    public void updateSwitches() {
        updateOptions();
    }

    private void showConfigDialog() {
        java.util.Map<String, String> zNewConfig = JStellaConfigurationDialog.runJStellaConfiguration(this, myConfiguration);
        if (zNewConfig != null) {
            myConfiguration = zNewConfig;
            saveConfig();
            myIntercessor.updateTelevisionMode();
        }//end : new config



    }

    private void loadNextGame() {
        try {
            if (myCurrentROMFile != null) {
                File[] zFileArray = FCMain.getCurrentDirectory().listFiles();
                java.util.List<File> zFileList = java.util.Arrays.asList(zFileArray);
                int zIndex = zFileList.indexOf(myCurrentROMFile);
                boolean zBreak = false;
                do {
                    zIndex++;
                    if (zIndex >= zFileArray.length) {
                        zBreak = true;
                    } else if (zFileArray[zIndex].getName().toLowerCase().endsWith(".bin") == true) {
                        loadROM(zFileArray[zIndex]);
                        zBreak = true;
                    }//end: is bin file
                } while (zBreak == false);
            }//end : not null
        }//end : try
        catch (IOException e) {
            e.printStackTrace();
        }



    }

    private boolean loadConfig() {
        boolean zSuccess = false;
        try {
            String zWorkingDir = System.getProperty("user.dir");
            if (zWorkingDir == null) {
                zWorkingDir = "";
            }
            File zCfgFile = new File(zWorkingDir, CONFIG_FILENAME);
            if (zCfgFile.exists() == true) {
                BufferedReader zBR = new BufferedReader(new FileReader(zCfgFile));
                boolean zEndOfFile = false;
                while (zEndOfFile == false) {
                    String zLine = zBR.readLine();
                    if (zLine == null) {
                        zEndOfFile = true;
                    } else {
                        int zEqualIndex = zLine.indexOf("=");
                        if (zEqualIndex != -1) {
                            String zKey = zLine.substring(0, zEqualIndex);
                            String zValue = zLine.substring(zEqualIndex + 1);
                            myConfiguration.put(zKey, zValue);
                        }//end : line has equal sign
                    }//end : not end of file
                }//end : while loop
                zBR.close();
                zSuccess = true;
            }//end : exists
            else {
                System.out.println("JStella configuration file does not exist");
            }


        }//end : try
        catch (IOException e) {
            e.printStackTrace();
        }
        return zSuccess;
    }

    private void saveConfig() {
        try {
            String zWorkingDir = System.getProperty("user.dir");
            if (zWorkingDir == null) {
                zWorkingDir = "";
            }
            File zCfgFile = new File(zWorkingDir, CONFIG_FILENAME);
            //boolean zExists=zCfgFile.exists();
            if (zCfgFile.exists() == false) {
                zCfgFile.createNewFile();
            }
            if (zCfgFile.exists() == true) {
                BufferedWriter zBW = new BufferedWriter(new FileWriter(zCfgFile));
                java.util.List<String> zKeyList = new java.util.ArrayList<String>(myConfiguration.keySet());
                for (String zKey : zKeyList) {
                    String zValue = myConfiguration.get(zKey);
                    zBW.write("" + zKey + "=" + zValue);
                    zBW.newLine();
                }//end : for key list loop
                zBW.close();
            }//end : exists (can be created)


        }//end : try
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    public java.util.Map<String, String> getConfiguration() {
        return myConfiguration;
    }

    /* public boolean isOkayToAutoPause() {
     return true;
     }
     */
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton ButtonAboutOK;
    private javax.swing.ButtonGroup ButtonGroupChannels;
    private javax.swing.ButtonGroup ButtonGroupP0Difficulty;
    private javax.swing.ButtonGroup ButtonGroupP1Difficulty;
    private javax.swing.ButtonGroup ButtonGroupTVType;
    private javax.swing.JCheckBoxMenuItem CBMILetterBoxMode;
    private javax.swing.JCheckBoxMenuItem CBMIPaused;
    private javax.swing.JCheckBoxMenuItem CBMIPhosphorEnabled;
    private javax.swing.JCheckBoxMenuItem CBMISoundEnabled;
    private javax.swing.JDialog DialogAbout;
    private javax.swing.JFileChooser FCMain;
    private javax.swing.JMenuBar MBMain;
    private javax.swing.JMenuItem MIAbout;
    private javax.swing.JMenuItem MIChangeDisplayHeight;
    private javax.swing.JMenuItem MIChangeYStart;
    private javax.swing.JMenuItem MIConfigure;
    private javax.swing.JMenuItem MIEnableAdvancedMenu;
    private javax.swing.JMenuItem MIExit;
    private javax.swing.JMenuItem MIHelpContents;
    private javax.swing.JMenuItem MILoadROM;
    private javax.swing.JMenuItem MILoadState;
    private javax.swing.JMenuItem MIReset;
    private javax.swing.JMenuItem MISaveState;
    private javax.swing.JMenuItem MISelect;
    private javax.swing.JMenuItem MIVirtualJoystick;
    private javax.swing.JMenu MenuAdvanced;
    private javax.swing.JMenu MenuControls;
    private javax.swing.JMenu MenuFile;
    private javax.swing.JMenu MenuHelp;
    private javax.swing.JMenu MenuOptions;
    private javax.swing.JMenu MenuPlayer0Difficulty;
    private javax.swing.JMenu MenuPlayer1Difficulty;
    private javax.swing.JMenu MenuSoundChannels;
    private javax.swing.JMenu MenuSwitches;
    private javax.swing.JMenu MenuTVType;
    private javax.swing.JPanel PanelAboutSouth;
    private javax.swing.JRadioButtonMenuItem RBMIBWTelevision;
    private javax.swing.JRadioButtonMenuItem RBMIColorTelevision;
    private javax.swing.JRadioButtonMenuItem RBMIMonoSound;
    private javax.swing.JRadioButtonMenuItem RBMIPlayer0Amateur;
    private javax.swing.JRadioButtonMenuItem RBMIPlayer0Professional;
    private javax.swing.JRadioButtonMenuItem RBMIPlayer1Amateur;
    private javax.swing.JRadioButtonMenuItem RBMIPlayer1Professional;
    private javax.swing.JRadioButtonMenuItem RBMIStereoSound;
    private javax.swing.JSeparator SepFileA;
    private javax.swing.JSeparator SepFileB;
    private javax.swing.JSeparator SepFileC;
    private javax.swing.JSeparator SepOptionsA;
    private javax.swing.JSeparator SepOptionsB;
    private javax.swing.JSeparator SepOptionsC;
    private javax.swing.JTextPane TPAbout;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItem2;
    private javax.swing.JMenuItem jMenuItem3;
    private javax.swing.JMenuItem jMenuItem4;
    private javax.swing.JMenuItem jMenuItem5;
    // End of variables declaration//GEN-END:variables

    public static class JSFileFilter extends javax.swing.filechooser.FileFilter {

        public final static String[] myRomExtensions = {"bin", "a26"};
        public final static String[] myJStellaStates = {"jssg"};
        public final static JSFileFilter FILTER_ROMS = new JSFileFilter("2600 ROM file (*.bin, *.a26)", myRomExtensions);
        public final static JSFileFilter FILTER_JSTELLA_STATE = new JSFileFilter("JStella saved game (*.jssg)", myJStellaStates);
        private String myDescription = "";
        private String[] myExtensions = {};

        public JSFileFilter(String aDescription, String[] aExtensionSet) {
            myDescription = aDescription;
            myExtensions = aExtensionSet;
        }

        public String getDescription() {
            return myDescription;
        }

        public boolean accept(File f) {
            if ((f != null) && (validExtension(f, myExtensions))) {
                return true;
            } else if (f.isFile() == false) {
                return true;
            } else {
                return false;
            }
        }

        public boolean validExtension(File f, String[] aExtensionSet) {
            for (String thisExtension : aExtensionSet) {
                if (f.getPath().toLowerCase().endsWith("." + thisExtension.toLowerCase()) == true) {
                    return true;
                }
            }
            return false;
        }
    }
    /*
     //==========================================================
     private class JStellaKeyListener extends java.awt.event.KeyAdapter {

     public void keyPressed(KeyEvent e) {
            
     System.out.println("a che serve??");
            
     if (e.getKeyCode() == KeyEvent.VK_F12) {
     loadNextGame();
     }
     }
     }
     */
}
